import java.sql.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Date;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author debroizr
 */
public class Reservation {
    
    public static void reservation(Connection conn) throws SQLException{
        System.out.println("\n*** Passer une réservation : ***"); 
        passerReservation(conn);
    }
    
    /**
     * passerReservation effectue les opérations nécessaires à la réservation
     * d'un vol.
     *
     * @param conn : Connexion à la base de donnée
     * @throws SQLException : Rollback si la transcation a rencontré une erreur.
     */
    private static void passerReservation(Connection conn) throws SQLException {
        PreparedStatement stmt;
        Vector listeVol = new Vector();
        int numClient;
        int numResa;
        int numVol;
        float Volume;
        float Poids;
        String dateVol;
        String typeVol;
        Scanner sc = new Scanner(System.in);
        String correspondance;
        int Prix = 500;
        
        Date actuelle = new Date();
        DateFormat dateFormat = new SimpleDateFormat("DD-MM-YYYY");
        String dateActuelle = dateFormat.format(actuelle);
        
        try {
            numClient = LectureClavier.lireEntier("Quel est votre numéro client ?");
            
            stmt = conn.prepareStatement("Select Points From Client Where NumClient = " + numClient);
            ResultSet resultat = stmt.executeQuery();
            resultat.next();
            int nbPoints = resultat.getInt("Points");
            
            if(nbPoints >= 100) {
                System.out.println("Voulez-vous utiliser vos points ?");
                String rep = LectureClavier.lireChaine();
                if(rep.equals("oui")) {
                    Prix = 0;
                    
                    /* Choix du niveau d'isolation */
                    conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                    
                    // Mise à jour des points du client
                    stmt = conn.prepareStatement("Update Client Set Points = 0 Where NumClient = " + numClient);
                    stmt.executeQuery();
                }
            } 
            
            stmt = conn.prepareStatement("Select count(numResa) as nbResa From Reservation");
            resultat = stmt.executeQuery();
            resultat.next();
            numResa = Integer.parseInt(resultat.getString("nbResa")) + 1;
            
            /* Choix du niveau d'isolation */
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                
            //Création de la première réservation
            stmt = conn.prepareStatement("Insert Into Reservation Values (?, ?, to_date(?, 'DD-MM-YY'))");
            stmt.setInt(1, numResa);
            stmt.setInt(2, numClient);
            stmt.setString(3, dateActuelle);
            
            stmt.executeQuery();
            
            System.out.println("Quel type de vol voulez-vous réserver ? (Fret/Passager)");
            typeVol = LectureClavier.lireChaine();
            
            if(typeVol.equals("Fret")) {
                //Vols disponibles à la réservation
                stmt = conn.prepareStatement("Select NumVolF, DateVolF From VolsFret Where NumVolF "
                        + "Not in(Select NumVolF From VolsFret Join ResaFret On NumVolF = NumVol)");
                
                resultat = stmt.executeQuery();
                while (resultat.next()) {
                    //Affichage des vols
                    numVol = Integer.parseInt(resultat.getString("NumVolF"));
                    dateVol = resultat.getString("DateVolF");
                    System.out.println("Numéro de vol non réservé : " + numVol + " Date du vol : " + dateVol);
                    listeVol.add(numVol);
                }
                
                numVol = LectureClavier.lireEntier("Veuillez indiquer le vol à réserver :");
                
                //Verification du vol
                while (!Suppression.volExistant(numVol, listeVol)) {
                    numVol = sc.nextInt();
                } 
                
                System.out.println("Date du vol à réserver (format DD-MM-YY) :");
                dateVol = LectureClavier.lireChaine();
                
                Volume = LectureClavier.lireFloat("Quel est le volume de votre chargement ?");
                Poids = LectureClavier.lireFloat("Quel est le poids de votre chargement ?");
                
                while(!verifVolumePoids(conn, Volume, Poids, numVol)) {
                    Volume = LectureClavier.lireFloat("Quel est le volume de votre chargement ?");
                    Poids = LectureClavier.lireFloat("Quel est le poids de votre chargement ?");
                }
                
                /* Choix du niveau d'isolation */
                conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                
                //Ajout de la réservation
                stmt = conn.prepareStatement("Insert Into ResaFret "
                        + "Values (?, to_date(?, 'DD-MM-YY'), ?, ?, ?, ?)");
                stmt.setInt(1, numVol);
                stmt.setString(2, dateVol);
                stmt.setInt(3, numResa);
                stmt.setFloat(4, Volume);
                stmt.setFloat(5, Poids);
                stmt.setInt(6, Prix);
                
                stmt.executeQuery();
                
                System.out.println("Avez-vous des correspondances ? (oui/non)");
                correspondance = LectureClavier.lireChaine();
                
                if(correspondance.equals("oui")) {
                    while(correspondance.equals("oui")) {
                        numVol = LectureClavier.lireEntier("Veuillez indiquer la correspondance à réserver :");

                        //Verification du vol
                        while (!Suppression.volExistant(numVol, listeVol)) {
                            numVol = sc.nextInt();
                        } 

                        System.out.println("Date de la correspondance à réserver (format DD-MON-YY) :");
                        dateVol = LectureClavier.lireChaine();
                        
                        Volume = LectureClavier.lireFloat("Quel est le volume de votre chargement ?");
                        Poids = LectureClavier.lireFloat("Quel est le poids de votre chargement ?");

                        while(!verifVolumePoids(conn, Volume, Poids, numVol)) {
                            Volume = LectureClavier.lireFloat("Quel est le volume de votre chargement ?");
                            Poids = LectureClavier.lireFloat("Quel est le poids de votre chargement ?");
                        }

                        /* Choix du niveau d'isolation */
                        conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
                        
                        //Ajout de la réservation
                        stmt = conn.prepareStatement("Insert Into ResaFret "
                                + "Values (?, trunc(DateVolF) = to_date(?, 'DD-MM-YY'), ?, ?, ?, ?)");
                        stmt.setInt(1, numVol);
                        stmt.setString(2, dateVol);
                        stmt.setInt(3, numResa);
                        stmt.setFloat(4, Volume);
                        stmt.setFloat(5, Poids);
                        stmt.setInt(6, Prix);
                        
                        stmt.executeQuery();
                        
                        System.out.println("Avez-vous des correspondances ? (oui/non)");
                        correspondance = LectureClavier.lireChaine();
                    }
                }
                
                System.out.println("Votre (vos) réservation(s) a (ont) été bien enregistrée(s).");
                
                //Si la transaction est validée on commit
                conn.commit();
                
                //AirChance
                AirChance.menu();
            }
            
            else if(typeVol.equals("Passager")) {
                int numPlace = 1;                
                
                //Vols disponibles à la réservation
                stmt = conn.prepareStatement("Select NumVolP, DateVolP From VolsPassagers Where NumVolP "
                        + "Not in(Select NumVolP From VolsPassagers Join ResaPassager On NumVolP = NumVolP)");
                
                resultat = stmt.executeQuery();
                while (resultat.next()) {
                    //Affichage des vols
                    numVol = Integer.parseInt(resultat.getString("NumVolP"));
                    dateVol = resultat.getString("DateVolP");
                    System.out.println("Numéro de vol non réservé : " + numVol + " Date du vol : " + dateVol);
                    listeVol.add(numVol);
                }
                
                numVol = LectureClavier.lireEntier("Veuillez indiquer le vol à réserver :");
                
                //Verification du vol
                while (!Suppression.volExistant(numVol, listeVol)) {
                    numVol = sc.nextInt();
                } 
                
                System.out.println("Date du vol à réserver (format DD-MM-YY) :");
                dateVol = LectureClavier.lireChaine();
                
                //Places disponibles
                stmt = conn.prepareStatement("Select NumPlace From Places Natural Join VolsPassagers"
                        + " Where NumVolP = " + numVol
                        + " Minus Select NumPlace From ResaPassager"
                        + " Where NumVolP = " + numVol);
                
                resultat = stmt.executeQuery();
                while (resultat.next()) {
                    //Affichage des vols
                    numPlace = Integer.parseInt(resultat.getString("NumPlace"));
                    System.out.println("Numéro de place disponible : " + numPlace);
                }
                
                //Ajout de la réservation
                stmt = conn.prepareStatement("Insert Into ResaPassager "
                        + "Values (?, to_date(?, 'DD-MM-YY'), ?, ?, ?)");
                stmt.setInt(1, numVol);
                stmt.setString(2, dateVol);
                stmt.setInt(3, numPlace);
                stmt.setFloat(4, numResa);
                stmt.setFloat(5, Prix);
                
                stmt.executeQuery();
                
                System.out.println("Avez-vous des correspondances ? (oui/non)");
                correspondance = LectureClavier.lireChaine();
                
                if(correspondance.equals("oui")) {
                    while(correspondance.equals("oui")) {
                        numVol = LectureClavier.lireEntier("Veuillez indiquer la correspondance à réserver :");

                        //Verification du vol
                        while (!Suppression.volExistant(numVol, listeVol)) {
                            numVol = sc.nextInt();
                        } 

                        System.out.println("Date de la correspondance à réserver (format DD-MON-YY) :");
                        dateVol = LectureClavier.lireChaine();
                        
                        //Places disponibles
                        stmt = conn.prepareStatement("Select NumPlace From Places Natural Join VolsPassagers"
                                + " Where NumVolP = " + numVol
                                + " Minus Select NumPlace From ResaPassager"
                                + " Where NumVolP = " + numVol);

                        resultat = stmt.executeQuery();
                        while (resultat.next()) {
                            //Affichage des vols
                            numPlace = Integer.parseInt(resultat.getString("NumPlace"));
                            System.out.println("Numéro de place disponible : " + numPlace);
                        }

                        //Ajout de la réservation
                        stmt = conn.prepareStatement("Insert Into ResaPassager "
                                + "Values (?, to_date(?, 'DD-MM-YY'), ?, ?, ?)");
                        stmt.setInt(1, numVol);
                        stmt.setString(2, dateVol);
                        stmt.setInt(3, numPlace);
                        stmt.setFloat(4, numResa);
                        stmt.setFloat(5, Prix);
                        
                        stmt.executeQuery();
                        
                        System.out.println("Avez-vous des correspondances ? (oui/non)");
                        correspondance = LectureClavier.lireChaine();
                    }
                }
                
                System.out.println("Votre (vos) réservation(s) a (ont) été bien enregistrée(s).");
                
                //Si la transaction est validée on commit
                conn.commit();
                
                //AirChance
                AirChance.menu();
            }
            
            else {
                System.out.println("Vol non valide.");
                AirChance.menu();
            }
            
        } catch (SQLException ex) {
            conn.rollback();
            System.out.println("La réservation du vol a rencontré une erreur.");
            Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public static boolean verifVolumePoids(Connection conn, float Volume, float Poids, int numVol) throws SQLException {
        Boolean volumePoidsOK = false;
        PreparedStatement stmt;
        float volumeMax;
        float poidsMax;
        
        try {
            stmt = conn.prepareStatement("Select Distinct VolumeMax, PoidsMax From AvionsFret"
                    + " Natural Join VolsFret"
                    + " Where NumVolF = " + numVol);
            ResultSet resultat = stmt.executeQuery();
            resultat.next();
            volumeMax = resultat.getFloat("VolumeMax");
            poidsMax = resultat.getFloat("PoidsMax");
            stmt.close();
            
            if(volumeMax > Volume) {
                volumePoidsOK = true;
            }
            
            if(poidsMax > Poids) {
                volumePoidsOK = true;
            }
            
            if(volumeMax < Volume || poidsMax < Poids) {
                volumePoidsOK = false;
                System.out.println("Le poids ou le volume dépasse les capacités de l'avion. Veuillez recommencer.");                 
            }
            
        } catch (SQLException ex) {
            conn.rollback();
            System.out.println("La vérification du poids et du volume a rencontré une erreur.");
            Logger.getLogger(AirChance.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return volumePoidsOK;
    }
}
